package com.zcgk.core.utils;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zcgk.core.domain.CodeMsg;
import com.zcgk.core.domain.DefaultPage;
import com.zcgk.core.exception.CosyException;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/****************************************************
 *
 * 分页工具
 *
 *
 * @author Francis
 * @date 2020/2/4 20:19
 * @version 1.0
 **************************************************/
public abstract class PageUtils {
    public static final Long DEFAULT_PAGE_SIZE = 20L;

    private static final String ORDER_STAGE_SPLITTER = ",";

    private static final String POINT = "\\.";

    private static final String ASC = "asc";

    private static final String DESC = "desc";


    /**
     * 对外调用： 将 defaultPage 转换成 分页插件对象
     *
     * @param defaultPage defaultPage 对象
     * @return mybatis-plus 分页对象
     */
    public static <T> Page<T> trans2Page(DefaultPage<T> defaultPage) {
        return PageUtils.trans2Page(defaultPage, DEFAULT_PAGE_SIZE);
    }


    /**
     * 对外调用： 将 defaultPage 对象转换成 mybatis-plus 的分页对象
     *
     * @param defaultPage     defaultPage 对象
     * @param defaultPageSize 默认分页数 可手动定义
     * @return mybatis-plus 分页对象
     */
    public static <T> Page<T> trans2Page(DefaultPage<T> defaultPage, Long defaultPageSize) {
        Page<T> result = new Page<T>();
        if (Objects.isNull(defaultPage)) {
            return result;
        }

        List<String> ascList = new ArrayList<>();
        List<String> descList = new ArrayList<>();
        if (!StringUtils.isEmpty(defaultPage.getOrderRules())) {
            for (String rule : defaultPage.getOrderRules().split(ORDER_STAGE_SPLITTER)) {
                try {
                    String[] args = rule.split(POINT);
                    switch (args[1].toLowerCase()) {
                        case ASC:
                            ascList.add(trans2UnderLine(args[0]));
                            break;
                        case DESC:
                            descList.add(trans2UnderLine(args[0]));
                            break;
                        default:
                            throw new CosyException(CodeMsg.BIND_ERROR);
                    }
                } catch (ArrayIndexOutOfBoundsException e) {
                    throw new CosyException(CodeMsg.BIND_ERROR);
                }
            }
        }

        result.setSize(null == defaultPage.getPageSize() || defaultPage.getPageSize() <= 0 ? defaultPageSize : defaultPage.getPageSize());
        result.setCurrent(null == defaultPage.getCurrentPage() || defaultPage.getCurrentPage() <= 0 ? 1 : defaultPage.getCurrentPage());
        result.setSearchCount(null == defaultPage.getSearchCount() || defaultPage.getSearchCount());
        result.setAscs(ascList);
        result.setDescs(descList);

        return result;
    }


    /**
     * mybatis-plus 分页对象转换成 defaultPage 对象
     *
     * @param page 插件分页对象
     * @return DefaultPage 分页对象
     */
    public static <T> DefaultPage<T> trans2DefaultPage(Page<T> page) {
        DefaultPage<T> result = new DefaultPage<T>();
        if (null == page) {
            return result;
        }
        result.setCurrentPage(page.getCurrent());
        result.setPageSize(page.getSize());
        result.setTotalPage(page.getPages());
        result.setTotalRecords(page.getTotal());
        return result;
    }


    /**
     * 将驼峰命名转为数据库命名方式
     *
     * @param camelCaseStr 驼峰命名字段
     * @return 返回数据库字段名
     */
    private static String trans2UnderLine(String camelCaseStr) {
        if (StringUtils.isEmpty(camelCaseStr)) {
            return "";
        }

        List<Integer> asiciiList = new ArrayList<>();
        char[] chars = camelCaseStr.toCharArray();
        for (int i = 0; i < chars.length; i++) {
            if (chars[i] >= 'A' && chars[i] <= 'Z') {
                asiciiList.add(i);
            }
        }

        if (asiciiList.size() == 0) {
            return camelCaseStr;
        }

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < asiciiList.size(); i++) {
            int first = asiciiList.get(i);
            int then = i == 0 ? asiciiList.get(i) : asiciiList.get(i) - asiciiList.get(i - 1) - 1;

            String result = camelCaseStr.substring(0, i == 0 ? first : then);
            sb.append(result).append("_").append(camelCaseStr.substring(i == 0 ? first : then, i == 0 ? first + 1 : then + 1).toLowerCase());

            camelCaseStr = camelCaseStr.substring(i == 0 ? first + 1 : then + 1);
            if (i == asiciiList.size() - 1) {
                sb.append(camelCaseStr);
            }
        }

        return sb.toString();
    }

}

